'''
    本模块维护了三个底层API接口

    - init         初始化本模块   导入该模块之后第一时间调用该方法以初始化视频模块
    - open_video   打开视频流     该api由内部init函数调用, 不提供给外部调用
    - get_img      获取一帧图像   将返回最新一帧图像
    - get_shape    获取图像shape  将返回图像的大小

    其中 对外开发的接口有 3 个 具体请看__all__列表

    举个例子:
        from . import video
        import cv2

        # 初始化 video 模块
        video.init()

        # 获取图像长宽
        print(f'图像的大小为 {video.shape}')

        # 获取一帧图像
        cv2.imshow('img', video.get_img())

=================================================================

    如果你希望视频流是经过处理之后才获得的话, 请重载本模块的方法

=================================================================

'''


import cv2
import threading
import copy


__all__ = ['init', 'get_shape', 'get_img']


init_flag = 0
video = None
shape = None
img = None

def video_init_flag(func):
    '''
        函数装饰器 video_init_flag

        该函数用于截断本模块的未初始化行为

        在使用本模块的方法之前, 需要先初始化本模块
        如果未初始化就进行调用, 会引发严重的错误
        因此封装了该装饰器, 来保证本模块的其他方法在本模块还未初始化的时候及时终止函数并提醒
    '''
    def new_func():
        if init_flag < 1:
            print('该模块还未初始化')
            return 
        return func()
    return new_func


def open_video():
    '''
        非必须的 api
        用于多线程获取 cv2 的视频流
        保证可以显示实时的视频流
    '''
    global img

    while True:
        _, img_ = video.read()
        img = copy.deepcopy(img_)


def init():
    '''
        必要 api
        用于定义本模块的初始化行为
    '''
    global init_flag
    global video
    global shape
    global img

    if init_flag == 1:
        return 
    video = cv2.VideoCapture(0)
    # video = cv2.VideoCapture('rtsp://192.168.0.110:8554/live')
    threading.Thread(target=open_video).start()
    print('正在开启视频流 . . .')
    while img is None:
        pass
    shape = img.shape[:2]
    print('视频流读取成功 . . .')
    print(f'视频大小为 {shape}')
    init_flag += 1

@video_init_flag
def get_shape():
    '''
        必要 api
        用于定义本模块视频流大小
    '''
    return shape

@video_init_flag
def get_img():
    '''
        必要 api
        用于定义本模块获取一帧图像的方式
    '''
    return copy.deepcopy(img)
